/*************************************************************************
	Slider

*************************************************************************/

using UnityEngine;
using System;
using System.Collections;
using System.Reflection;

[Serializable]
public class UKagSlider_SaveData : UKagControlBase_SaveData
{
	public UKagSlider_SaveData() {}
		
	public bool isVertical = false;
	public int step = 0;
	public float minValue = 0;
	public float maxValue = 100.0f;
	public float currValue = 0;
	
	public string eventTarget = null;
	public string eventParam = null;
	public string valueProperty = null;
}

[RequireComponent(typeof(UTVPAnimationLayer))]
public class UKagSlider : UKagControlBase {
	
	public enum CONTROL_STATE
	{
		NORMAL,
		OVER,
		ON,
		DISABLE,
		
		SIZE
	}
	
	public static string[] tabStateSuffix = { "TabNormal", "TabOver", "TabOn", "TabDisable" };
	public static string[] baseStateSuffix = { "BaseNormal", "BaseSelected", "BaseSelected", "BaseDisable" };
	
	public bool isVertical = false;
	public int step = 0;
	protected bool tabDragging = false;
	
	protected float _minValue = 0;
	protected float _maxValue = 100.0f;
	protected float _currValue = 0;
	public float minValue
	{
		get { return _minValue; }
		set
		{
			if (_minValue == value)
				return;
			_minValue = value;
			
			RefreshTabPos();
		}
	}
	public float maxValue
	{
		get { return _maxValue; }
		set
		{
			if (_maxValue == value)
				return;
			_maxValue = value;
			
			RefreshTabPos();
		}
	}
	public float currValue
	{
		get { return _currValue; }
		set
		{
			if (_currValue == value)
				return;
			_currValue = value;
			
			RefreshTabPos();
		}
	}
	
	private int dragDX, dragDY;
	private PropertyInfo valueProperty = null;
	
	public GameObject eventTarget = null;
	private string eventParam = null;
	
	protected UTVPAnimationLayer mTabLayer = null;
	public UTVPAnimationLayer tabLayer { get { return mTabLayer; } }
	
	public void SetValueProperty(string propertyName)
	{
		if (propertyName != null || propertyName == "")
		{
			valueProperty = mSystem.extFunc.GetType().GetProperty(propertyName);
			if (valueProperty != null)
				currValue = (float)valueProperty.GetValue(mSystem.extFunc, null);
		}
		else
			valueProperty = null;
	}
	
	protected virtual void OnValueChanged()
	{
		valueProperty.SetValue(mSystem.extFunc, _currValue, null);
	}
	
	// Use this for initialization
	protected override void Awake () {
		base.Awake();
		
		mTabLayer = UTVPLayer.CreateLayer<UTVPAnimationLayer>(mSystem, mTargetLayer, "tab", 10);
		mTabLayer.HitType = UTVPLayer.HIT_TYPE.ALWAYS;
		
		mLayerObjs = new UTVPAnimationLayer[2];
		mLayerObjs[0] = mTargetLayer;
		mLayerObjs[1] = mTabLayer;
		
		if (eventParam == null)
			eventParam = this.name;
	}
	
	protected override void Start () {
		base.Start();
		
		mTabLayer.Visible = true;
	}
	
	public void SetSliderOpt(UTVPImage img, string animPrefix, string isVerticalStr,
		string leftStr, string topStr, string widthStr, string heightStr,
		string tabWidthStr, string tabHeightStr)
	{
		mTargetLayer.LoadImage(img);
		mTabLayer.LoadImage(img);
		stateAnimNamePrefix = animPrefix;
		this.isVertical = mSystem.Str2Bool(isVerticalStr);
		
		UTVPAnimFrameInfo baseFrame = img.frameDic[img.sequenceDic[animPrefix + baseStateSuffix[(int)CONTROL_STATE.NORMAL]].frames[0]];
		UTVPAnimFrameInfo tabFrame = img.frameDic[img.sequenceDic[animPrefix + tabStateSuffix[(int)CONTROL_STATE.NORMAL]].frames[0]];
		
		int left = mTargetLayer.Left;
		mSystem.Str2Number(leftStr, ref left);
		int top = mTargetLayer.Top;
		mSystem.Str2Number(topStr, ref top);
		int width = baseFrame.w;
		mSystem.Str2Number(widthStr, ref width);
		int height = baseFrame.h;
		mSystem.Str2Number(heightStr, ref height);
		mTargetLayer.SetPosAndSize(left, top, width, height);

		int tabWidth = tabFrame.w;
		mSystem.Str2Number(tabWidthStr, ref tabWidth);
		int tabHeight = tabFrame.h;
		mSystem.Str2Number(tabHeightStr, ref tabHeight);
		mTabLayer.SetPosAndSize(0, 0, tabWidth, tabHeight);
		
		RefreshControlState();
	}
	
	public void setValue(float min, float max, float value)
	{
		_minValue = min;
		_maxValue = max;
		_currValue = value;
		
		RefreshTabPos();
	}
	
	protected override void RefreshControlState()
	{
		if (mDisable)
		{
			mTabLayer.StartAnimation(stateAnimNamePrefix + tabStateSuffix[(int)CONTROL_STATE.DISABLE], 0, false);
			mTargetLayer.StartAnimation(stateAnimNamePrefix + baseStateSuffix[(int)CONTROL_STATE.DISABLE], 0, false);
		}
		else if (mMouseDown)
		{
			mTabLayer.StartAnimation(stateAnimNamePrefix + tabStateSuffix[(int)CONTROL_STATE.ON], 0, false);
			mTargetLayer.StartAnimation(stateAnimNamePrefix + baseStateSuffix[(int)CONTROL_STATE.ON], 0, false);
		}
		else if (mFocus)
		{
			mTabLayer.StartAnimation(stateAnimNamePrefix + tabStateSuffix[(int)CONTROL_STATE.OVER], 0, false);
			mTargetLayer.StartAnimation(stateAnimNamePrefix + baseStateSuffix[(int)CONTROL_STATE.OVER], 0, false);
		}
		else
		{
			mTabLayer.StartAnimation(stateAnimNamePrefix + tabStateSuffix[(int)CONTROL_STATE.NORMAL], 0, false);
			mTargetLayer.StartAnimation(stateAnimNamePrefix + baseStateSuffix[(int)CONTROL_STATE.NORMAL], 0, false);
		}
		
		RefreshTabPos();
	}
	
	protected void RefreshTabPos()
	{
		if (_currValue < _minValue)
			_currValue = _minValue;
		if (_currValue > _maxValue)
			_currValue = _maxValue;

		if (isVertical)
			mTabLayer.Top = (int)((mTargetLayer.Height - mTabLayer.Height) * (_currValue - _minValue) / (_maxValue - _minValue));
		else
			mTabLayer.Left = (int)((mTargetLayer.Width - mTabLayer.Width) * (_currValue - _minValue) / (_maxValue - _minValue));
	}
	
	protected override void OnMouseMove_impl(UTVPLayer layer, int x, int y, float dx, float dy, int shift)
	{
		base.OnMouseMove_impl(layer, x, y, dx, dy, shift);
		
		if (tabDragging)
			OnMouseMove_slider(x, y);
	}
	
	private void OnMouseMove_slider(int x, int y)
	{
		if (isVertical)
		{
			y -= dragDY;
			if (y < 0)
				y = 0;
			if (y > mTargetLayer.Height - mTabLayer.Height)
				y = mTargetLayer.Height - mTabLayer.Height;

			float valueTemp = _minValue + ((float)y) / (mTargetLayer.Height - mTabLayer.Height) * (_maxValue - _minValue);
				if(step != 0)
				{
					int valueTempInt = (int)(valueTemp + 0.5f);
					if (step > 1)
						valueTempInt = valueTempInt - valueTempInt % step;
					if (valueTempInt != (int)_currValue)
					{
						_currValue = valueTempInt;
						RefreshTabPos();
						OnValueChanged();
					}
					else
						_currValue = valueTempInt;
				}
				else
				{
					_currValue = valueTemp;
					mTabLayer.Top = y;
					OnValueChanged();
				}
			
		}
		else
		{
			x -= dragDX;
			if (x < 0)
				x = 0;
			if (x > mTargetLayer.Width - mTabLayer.Width)
				x = mTargetLayer.Width - mTabLayer.Width;

				float valueTemp = _minValue + ((float)x) / (mTargetLayer.Width - mTabLayer.Width) * (_maxValue - _minValue);
				if(step != 0)
				{
					int valueTempInt = (int)(valueTemp + 0.5f);
					if (step > 1)
						valueTempInt = valueTempInt - valueTempInt % step;
					if (valueTempInt != (int)_currValue)
					{
						_currValue = valueTempInt;
						RefreshTabPos();
						OnValueChanged();
					}
					else
						_currValue = valueTempInt;
				}
				else
				{
					_currValue = valueTemp;
					mTabLayer.Left = x;
					OnValueChanged();
				}
			
		}
	}
	
	protected override void OnMouseDown_impl(UTVPLayer layer, int x, int y, KeyCode button, int shift)
	{
		base.OnMouseDown_impl(layer, x, y, button, shift);
		
		if (layer == mTabLayer)
		{
			tabDragging = true;
			dragDX = x - mTabLayer.Left;
			dragDY = y - mTabLayer.Top;
		}
		else
		{
			x -= mTabLayer.Width / 2;
			y -= mTabLayer.Height / 2;
			if (x < 0)
				x = 0;
			if (x > mTargetLayer.Width - mTabLayer.Width)
				x = mTargetLayer.Width - mTabLayer.Width;
			if (y < 0)
				y = 0;
			if (y > mTargetLayer.Height - mTabLayer.Height)
				y = mTargetLayer.Height - mTabLayer.Height;
			
			dragDX = 0;
			dragDY = 0;
			OnMouseMove_slider(x, y);
		}
		
		if (eventTarget != null)
			eventTarget.SendMessage("OnButtonClick", eventParam, SendMessageOptions.DontRequireReceiver);	
	}
	
	protected override void OnMouseUp_impl(UTVPLayer layer, int x, int y, KeyCode button, int shift)
	{
		base.OnMouseUp_impl(layer, x, y, button, shift);
		
		tabDragging = false;
		
		if (eventTarget != null)
			eventTarget.SendMessage("OnButtonClick", eventParam, SendMessageOptions.DontRequireReceiver);	
	}
	
	protected override void OnMouseEnter_impl(UTVPLayer layer)
	{
		base.OnMouseEnter_impl(layer);
		
		if (eventTarget != null)
			eventTarget.SendMessage("OnButtonMouseEnter", eventParam, SendMessageOptions.DontRequireReceiver);
	}
	
	protected override void OnMouseLeave_impl(UTVPLayer layer)
	{
		base.OnMouseLeave_impl(layer);
		
		tabDragging = false;
		
		if (eventTarget != null)
			eventTarget.SendMessage("OnButtonMouseLeave", eventParam, SendMessageOptions.DontRequireReceiver);
	}
	
	protected override UKagControlBase_SaveData CreateSaveDataBuff()
	{
		return new UKagSlider_SaveData(); 
	}
	
	protected override void GetSelfData(UKagControlBase_SaveData dataBuff)
	{
		base.GetSelfData(dataBuff);
		
		UKagSlider_SaveData dataBuffSelf = (UKagSlider_SaveData)dataBuff;
		
		dataBuffSelf.isVertical = isVertical;
		dataBuffSelf.step = step;
		dataBuffSelf.maxValue = _maxValue;
		dataBuffSelf.minValue = _minValue;
		dataBuffSelf.currValue = _currValue;
		
		dataBuffSelf.eventTarget = eventTarget.name;
		dataBuffSelf.eventParam = eventParam;
		dataBuffSelf.valueProperty = valueProperty != null ? valueProperty.Name : null;
	}
	
	protected override void SetSelfData(UKagControlBase_SaveData dataBuff)
	{
		base.SetSelfData(dataBuff);
		
		UKagSlider_SaveData dataBuffSelf = (UKagSlider_SaveData)dataBuff;
		
		isVertical = dataBuffSelf.isVertical;
		step = dataBuffSelf.step;
		_maxValue = dataBuffSelf.maxValue;
		_minValue = dataBuffSelf.minValue;
		_currValue = dataBuffSelf.currValue;
		
		eventTarget = GameObject.Find(dataBuffSelf.eventTarget);
		eventParam = dataBuffSelf.eventParam;
		
		if (dataBuffSelf.valueProperty != null || dataBuffSelf.valueProperty == "")
			valueProperty = mSystem.extFunc.GetType().GetProperty(dataBuffSelf.valueProperty);
		else
			valueProperty = null;
	}
}
